package a02;

import java.awt.Cursor;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JSlider;
import util.SoundManager;

public class MainMenu<M> implements Constants {
    private JMenuBar gameMenu = new JMenuBar();
    private JMenu fileMenu = new JMenu("Datei");
    private JLabel statusMenu = new JLabel("");
    private JFrame frame;
    private RegularControl<?> control;
    private JButton undoButton;
    private JButton passButton;
    private JMenuItem[] menuItem = new JMenuItem[6];

    private JSlider slider;
    private JPanel mainPanel;
    private ChatBox chatBox;

    public MainMenu(RegularControl<?> regularControl) {
	this.control = regularControl;
    }

    public JFrame getFrame() {
	return this.frame;
    }

    public JMenuBar getMenu() {
	return this.gameMenu;
    }

    public void setStatus(String status) {
	setStatus(status, false);
    }

    public void setStatus(String status, boolean thinking) {
	this.statusMenu.setText(status + " ");
	if (thinking) {
	    this.statusMenu.setIcon(new ImageIcon(Icon.THINK));
	} else {
	    this.statusMenu.setIcon(null);
	}
    }

    public JFrame getNewFrame(String label) {
	this.gameMenu = new JMenuBar();
	this.fileMenu = new JMenu("Datei");
	this.frame = new JFrame(label);
	this.frame.setJMenuBar(this.gameMenu);
	this.gameMenu.add(this.fileMenu);
	this.gameMenu.add(infoMenu());
	this.gameMenu.add(Box.createHorizontalGlue());
	this.gameMenu.add(this.statusMenu);

	this.frame.addWindowListener(new WindowAdapter() {
	    public void windowClosing(WindowEvent _) {
		control.backToMenu();
	    }
	});
	addTheComponents();
	frame.setIconImage(Toolkit.getDefaultToolkit()
		.createImage(Icon.PROGRAM));
	return this.frame;
    }

    private JMenu infoMenu() {
	JMenu infoMenu = new JMenu("Info");
	JMenuItem infoItem = new JMenuItem(new AbstractAction(About.TITLE) {
	    private static final long serialVersionUID = 1L;

	    public void actionPerformed(ActionEvent e) {
		showInfo();
	    }

	    private void showInfo() {
		JDialog dialog = new JDialog();
		dialog.setIconImage(Toolkit.getDefaultToolkit().createImage(
			Icon.PROGRAM));
		JLabel label = new JLabel(About.TEXT);
		label.setCursor(new Cursor(Cursor.HAND_CURSOR));
		label.addMouseListener(new MouseAdapter() {
		    @Override
		    public void mouseClicked(MouseEvent e) {
			if (Desktop.isDesktopSupported()) {
			    try {
				Desktop.getDesktop().browse(new URI(About.URL));
			    } catch (IOException e1) {
				e1.printStackTrace();
			    } catch (URISyntaxException e1) {
				e1.printStackTrace();
			    }
			}
		    }
		});
		label.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		dialog.add(label);
		dialog.setTitle(About.TITLE);
		dialog.setPreferredSize(new Dimension(400, 150));
		dialog.pack();
		dialog.setLocationRelativeTo(control);
		dialog.setVisible(true);
	    }
	});
	infoItem.setIcon(loadIcon(Icon.ABOUT));
	infoMenu.add(infoItem);
	return infoMenu;
    }

    private void addTheComponents() {
	ImageIcon[] menuIcons = { loadIcon(Icon.REFRESH), loadIcon(Icon.OPEN),
		loadIcon(Icon.SAVE), loadIcon(Icon.BACK), loadIcon(Icon.EXIT) };

	menuItem[1] = new JMenuItem(new AbstractAction(MenuText.RESTART) {
	    private static final long serialVersionUID = 1L;

	    public void actionPerformed(ActionEvent e) {
		if (!(getControl() == null)) {
		    getControl().reset();
		}
	    }

	});
	menuItem[2] = new JMenuItem(new AbstractAction(MenuText.LOAD) {
	    private static final long serialVersionUID = 1L;

	    public void actionPerformed(ActionEvent e) {
		if (!(getControl() == null)) {
		    getControl().getSaveGameManager().load();

		}
	    }
	});
	menuItem[3] = new JMenuItem(new AbstractAction(MenuText.SAVE) {
	    private static final long serialVersionUID = 1L;

	    public void actionPerformed(ActionEvent e) {
		if (!(getControl() == null)) {
		    getControl().getSaveGameManager().save();
		}
	    }
	});
	menuItem[4] = new JMenuItem(new AbstractAction(MenuText.BACK) {
	    private static final long serialVersionUID = 1L;

	    public void actionPerformed(ActionEvent e) {
		control.backToMenu();
	    }
	});
	menuItem[5] = new JMenuItem(new AbstractAction(MenuText.EXIT) {
	    private static final long serialVersionUID = 1L;

	    public void actionPerformed(ActionEvent e) {
		System.exit(0);
	    }
	});

	for (int i = 1; i < 6; i++) {
	    this.menuItem[i].setIcon(menuIcons[i - 1]);
	    this.fileMenu.add(menuItem[i]);
	    if (i == 3)
		this.fileMenu.addSeparator();
	}
    }

    public void setLoadSaveEnabled(boolean e) {
	if (!e) {
	    for (int i = 1; i < 4; i++) {
		menuItem[i].setEnabled(false);
	    }
	}
    }

    private RegularControl<?> getControl() {
	return this.control;
    }

    private ImageIcon loadIcon(String fileName) {
	return new ImageIcon(OPTION_PATH + fileName);
    }

    public JPanel getPanel(int kiLevel) {
	JPanel mainPanel = new JPanel();
	JPanel topPanel = new JPanel();
	JPanel bottomPanel = new JPanel();
	JPanel outerPanel = new JPanel();
	initButtons();
	mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.PAGE_AXIS));
	outerPanel.setLayout(new BoxLayout(outerPanel, BoxLayout.LINE_AXIS));
	passButton.setIcon(new ImageIcon(Icon.PASS));
	topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.LINE_AXIS));
	createSlider(kiLevel);
	if (kiLevel > 0) {
	    slider.setBorder(BorderFactory.createTitledBorder(MenuText.SLIDER));
	    topPanel.add(slider);
	}
	topPanel.add(control);

	if (control.isPassingEnabled()) {
	    bottomPanel.setLayout(new GridLayout(1, 2));
	    bottomPanel.add(undoButton);
	    bottomPanel.add(passButton);
	} else {
	    bottomPanel.setLayout(new GridLayout(1, 1));
	    bottomPanel.add(undoButton);
	}

	mainPanel.add(topPanel);
	mainPanel.add(bottomPanel);
	outerPanel.add(mainPanel);
	this.mainPanel = outerPanel;
	return outerPanel;
    }

    private void initButtons() {
	this.undoButton = new JButton(" " + MenuText.UNDO);
	this.undoButton.setFont(FONT_12);
	this.undoButton.addActionListener(new ActionListener() {
	    public void actionPerformed(ActionEvent e) {
		playSound(Sound.UNDO);
		control.undo();
	    }
	});
	undoButton.setIcon(new ImageIcon(Icon.UNDO));
	undoButton.setEnabled(false);

	this.passButton = new JButton(" " + MenuText.PASS);
	this.passButton.setFont(FONT_12);

	this.passButton.addActionListener(new ActionListener() {
	    public void actionPerformed(ActionEvent e) {
		playSound(Sound.PASS);
		control.pass();
	    }
	});
    }

    public void setButtonEnabled(boolean enabled) {
	if (getControl().getServer() == null)
	    this.undoButton.setEnabled(enabled);
	this.slider.setEnabled(!enabled);
    }

    private void createSlider(int standard) {
	this.slider = new JSlider(JSlider.VERTICAL, 0, standard, standard);
	slider.setMajorTickSpacing(1);
	slider.setMinorTickSpacing(1);
	slider.setPaintTicks(true);
	slider.setPaintLabels(true);
	slider.setSnapToTicks(true);
    }

    public int getSkillLevel() {
	return this.slider.getValue();
    }

    public void playSound(String fileName) {
	if (control.isSoundEnabled()) {
	    new SoundManager(fileName).play();
	}
    }

    public void addChat() {
	chatBox = new ChatBox(control, this.frame.getHeight());
	mainPanel.add(chatBox);
	frame.pack();
    }

    public ChatBox getChat() {	
	return this.chatBox;
    }

  

}
